#include "wxssplitterwindow.h"

#include <wx/splitter.h>

namespace {
  wxsRegisterItem<wxsSplitterWindow> Reg( _T( "SplitterWindow" ), _T( "拆分窗口" ), wxsTContainer, _T( "布局" ), 30 );
  WXS_ST_BEGIN( wxsSplitterWindowStyles, _T( "wxSP_3D" ) )
  WXS_ST_CATEGORY( "wxSplitterWindow" )
  WXS_ST( wxSP_3D )
  WXS_ST( wxSP_3DSASH )
  WXS_ST( wxSP_3DBORDER )
  WXS_ST( wxSP_BORDER )
  WXS_ST( wxSP_NOBORDER )
  WXS_ST( wxSP_PERMIT_UNSPLIT )
  WXS_ST( wxSP_LIVE_UPDATE )
  WXS_ST( wxSP_NO_XP_THEME )
  WXS_ST_DEFAULTS()
  WXS_ST_END()
  WXS_EV_BEGIN( wxsSplitterWindowEvents )
  WXS_EVI( EVT_SPLITTER_SASH_POS_CHANGING, wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, wxSplitterEvent, SashPosChanging )
  WXS_EVI( EVT_SPLITTER_SASH_POS_CHANGED, wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, wxSplitterEvent, SashPosChanged )
  WXS_EVI( EVT_SPLITTER_UNSPLIT, wxEVT_COMMAND_SPLITTER_UNSPLIT, wxSplitterEvent, Unsplit )
  WXS_EVI( EVT_SPLITTER_DCLICK, wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, wxSplitterEvent, DClick )
  WXS_EV_END()
}

wxsSplitterWindow::wxsSplitterWindow( wxsItemResData* Data ):
  wxsContainer( Data, &Reg.Info, wxsSplitterWindowEvents, wxsSplitterWindowStyles ),
  SashPos( 0 ),
  MinPaneSize( 10 ),
  Orientation( wxHORIZONTAL ),
  SashGravity( 0.5f ) {
}

wxObject* wxsSplitterWindow::OnBuildPreview( wxWindow* Parent, long Flags ) {
  wxSplitterWindow* Splitter = new wxSplitterWindow( Parent, GetId(), Pos( Parent ), Size( Parent ), Style() );
  SetupWindow( Splitter, Flags );
  if( MinPaneSize != -1 ) {
    Splitter->SetMinimumPaneSize( MinPaneSize );
  }
  AddChildrenPreview( Splitter, Flags );
  if( GetChildCount() == 0 ) {
  } else if( GetChildCount() == 1 ) {
    Splitter->Initialize( wxDynamicCast( GetChild( 0 )->GetLastPreview(), wxWindow ) );
  } else {
    if( Orientation == wxHORIZONTAL ) {
      Splitter->SplitHorizontally(
        wxDynamicCast( GetChild( 0 )->GetLastPreview(), wxWindow ),
        wxDynamicCast( GetChild( 1 )->GetLastPreview(), wxWindow ),
        SashPos );
    } else {
      Splitter->SplitVertically(
        wxDynamicCast( GetChild( 0 )->GetLastPreview(), wxWindow ),
        wxDynamicCast( GetChild( 1 )->GetLastPreview(), wxWindow ),
        SashPos );
    }
    Splitter->SetSashGravity( SashGravity );
    Splitter->OnInternalIdle();
  }
  return Splitter;
}

void wxsSplitterWindow::OnBuildCreatingCode() {
  switch( GetLanguage() ) {
    case wxsCPP: {
      AddHeader( _T( "<wx/splitter.h>" ), GetInfo().ClassName, 0 );
      AddHeader( _T( "<wx/splitter.h>" ), _T( "wxSplitterEvent" ), 0 );
      Codef( _T( "%C(%W, %I, %P, %S, %T, %N);\n" ) );
      BuildSetupWindowCode();
      if( MinPaneSize != -1 ) {
        Codef( _T( "%ASetMinimumPaneSize(%d);\n" ), MinPaneSize );
      }
      Codef( _T( "%ASetSashGravity(%f);\n" ), SashGravity );
      AddChildrenCode();
      if( GetChildCount() == 0 ) {
      } else if( GetChildCount() == 1 ) {
        Codef( _T( "%AInitialize(%o);\n" ), 0 );
      } else {
        Codef( _T( "%ASplit%s(%o, %o);\n" ), ( ( Orientation == wxHORIZONTAL ) ? _T( "Horizontally" ) : _T( "Vertically" ) ), 0, 1 );
        if( SashPos != 0 ) {
          Codef( _T( "%ASetSashPosition(%d);\n" ), SashPos );
        }
      }
      break;
    }
    case wxsUnknownLanguage:
    default: {
      wxsCodeMarks::Unknown( _T( "wxsSplitterWindow::OnBuildCreatingCode" ), GetLanguage() );
    }
  }
}

void wxsSplitterWindow::OnEnumContainerProperties( M_Code_unused long Flags ) {
  static const long    OrientValues[] = { wxHORIZONTAL, wxVERTICAL, 0 };
  static const wxChar* OrientNames[]  = { _T( "horizontal" ), _T( "vertical" ), 0 };
  WXS_LONG( wxsSplitterWindow, SashPos, _T( "Sash position" ), _T( "sashpos" ), 0 );
  WXS_FLOAT( wxsSplitterWindow, SashGravity, _T( "Sash gravity" ), _T( "sashgravity" ), 0.5 );
  WXS_LONG( wxsSplitterWindow, MinPaneSize, _T( "Min. pane size" ), _T( "minpanesize" ), -1 );
  WXS_ENUM( wxsSplitterWindow, Orientation, _T( "Orientation" ), _T( "orientation" ), OrientValues, OrientNames, wxHORIZONTAL );
}

bool wxsSplitterWindow::OnCanAddChild( wxsItem* Item, bool ShowMessage ) {
  if( GetChildCount() == 2 ) {
    if( ShowMessage ) {
      wxMessageBox( _T( "Splitter can have at most 2 children" ) );
    }
    return false;
  }
  if( Item->GetType() == wxsTSizer ) {
    if( ShowMessage ) {
      wxMessageBox( _T( "Can not add sizer into Splitter.\nAdd panels first" ) );
    }
    return false;
  }
  if( Item->GetType() == wxsTSpacer ) {
    if( ShowMessage ) {
      wxMessageBox( _T( "Spacer can be added to sizers only" ) );
    }
    return false;
  }
  return true;
}
